<!--
 * Copyright © 2023
 * @Author: zhangxiang
 * @Date: 2023-04-06 17:18:32
 * @LastEditors: zhangxiang
 * @LastEditTime: 2023-10-18 10:30:57
 * @Description: 目前最多支持四个云商
 *
-->

<template>
  <div class="provider-topo-ctn">
    <div :id="'topo-root-' + formatTopoLength" class="topo-root"></div>
    <template v-for="(provider, pindex) in providerTopo">
      <div
        :id="'topo-' + formatTopoLength + '-provider-' + (pindex + 1)"
        :key="pindex"
        :class="[
          'topo-provider',
          provider.cloudProvider === 'Openstack' ? 'special' : '',
        ]"
        :style="{
          backgroundImage:
            'url(' + getProviderImg(provider.cloudProvider) + ')',
        }"
      ></div>
      <div
        :key="'provider-res' + pindex"
        :class="[
          'provider-res',
          'provider-res-' + formatTopoLength,
          'provider-res-' + formatTopoLength + '-' + (pindex + 1),
        ]"
      >
        <div
          v-for="(item, index) in provider.items"
          :id="
            'topo-' +
              formatTopoLength +
              '-provider-' +
              (pindex + 1) +
              '-res-' +
              (index + 1)
          "
          :key="pindex + '-' + index"
          :class="['topo-res']"
        >
          <img class="res-img" :src="getTopoResImg(item.key)" />
          <div class="res-text">{{ item.key }} {{ item.val }}</div>
        </div>
      </div>
    </template>
  </div>
</template>

<script>
import LeaderLine from 'leader-line'

export default {
  name: 'ProviderTopo',
  props: {
    providerTopo: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      leaderLines: [],
      // 连线的起始位置
      lineSockets: {
        root2provider: {
          len2: {
            start: ['left', 'right'],
            end: ['top', 'top']
          },
          len3: {
            start: ['left', 'right', 'bottom'],
            end: ['right', 'left', 'top']
          },
          len4: {
            start: ['left', 'right', 'bottom', 'bottom'],
            end: ['right', 'left', 'right', 'left']
          }
        },
        provider2res: {
          len2: {
            start: ['left', 'right'],
            end: ['right', 'left']
          },
          len3: {
            start: ['left', 'right', 'bottom'],
            end: ['right', 'left', 'top']
          },
          len4: {
            start: ['left', 'right', 'left', 'right'],
            end: ['right', 'left', 'right', 'left']
          }
        }
      },
      topoShow: true
    }
  },
  computed: {
    /**
     * @description: 格式化长度 限制为 2-4
     * @return {*}
     */
    formatTopoLength() {
      return Math.max(2, this.providerTopo.length)
    },
    /**
     * @description: 长度
     * @return {*}
     */
    topoLength() {
      return this.providerTopo.length
    }
  },
  watch: {
    topoLength: {
      handler(newVal) {
        this.startDrawLines()
      },
      immediate: true
    }
  },
  created() {},
  mounted() {},
  beforeDestroy() {
    for (const leaderLine of this.leaderLines) {
      leaderLine.remove()
    }
    this.leaderLines = []
  },
  methods: {
    /**
     * @description: 缩容容器变化事件响应处理
     * @return {*}
     */
    scaleChangeHandle() {
      if (this.topoShow) {
        this.startDrawLines()
      }
    },
    /**
     * @description: 拓扑展示处理
     * @param {*} visible
     * @return {*}
     */
    topoShowHandle(visible) {
      this.topoShow = visible
      if (visible) {
        this.startDrawLines()
      } else {
        // 拓扑图隐藏
        // 去除画线
        if (this.topoLength > 0) {
          for (const leaderLine of this.leaderLines) {
            leaderLine.remove()
          }
          this.leaderLines = []
        }
      }
    },
    /**
     * @description: 开始绘制
     * @return {*}
     */
    startDrawLines() {
      if (this.topoLength > 0) {
        for (const leaderLine of this.leaderLines) {
          leaderLine.remove()
        }
        this.leaderLines = []
        setTimeout(() => {
          if (this.topoShow) {
            this.drawLines()
          }
        }, 500)
      }
    },
    /**
     * @description: 绘制
     * @return {*}
     */
    drawLines() {
      const idRoot = 'topo-root-' + this.formatTopoLength
      this.providerTopo.forEach((element, pindex) => {
        // 云商画线
        const idProvider =
          'topo-' + this.formatTopoLength + '-provider-' + (pindex + 1)
        const startEle = document.getElementById(idRoot) // 起点
        const endEle = document.getElementById(idProvider) // 终点
        var leader_line = new LeaderLine(startEle, endEle, {
          color: '#F7E900',
          startSocket: this.computeStartSocket(
            'root2provider',
            'start',
            pindex
          ), // 在指引线开始的地方从元素左侧开始
          endSocket: this.computeStartSocket('root2provider', 'end', pindex), // 在指引线开始的地方从元素右侧结束
          size: 2,
          endPlug: 'behind',
          path: 'grid'
        })
        this.leaderLines.push(leader_line)
        // 资源画线
        element.items.forEach((item, itemIndex) => {
          const idRes =
            'topo-' +
            this.formatTopoLength +
            '-provider-' +
            (pindex + 1) +
            '-res-' +
            (itemIndex + 1)
          const startEle2 = document.getElementById(idProvider) // 起点
          const endEle2 = document.getElementById(idRes) // 终点
          var leader_line2 = new LeaderLine(startEle2, endEle2, {
            color: '#F7E900',
            startSocket: this.computeStartSocket(
              'provider2res',
              'start',
              pindex
            ), // 在指引线开始的地方从元素左侧开始
            endSocket: this.computeStartSocket('provider2res', 'end', pindex), // 在指引线开始的地方从元素右侧结束
            size: 2,
            endPlug: 'behind',
            path: 'grid'
          })
          this.leaderLines.push(leader_line2)
        })
      })
      LeaderLine.positionByWindowResize = false
    },
    /**
     * @description: 计算线条起始位置
     * @param {*} type
     * @param {*} socketType
     * @param {*} index
     * @return {*}
     */
    computeStartSocket(type, socketType, index) {
      return this.lineSockets[type]['len' + this.formatTopoLength][socketType][
        index
      ]
    },
    /**
     * @description: 资源图片
     * @param {*} key
     * @return {*}
     */
    getTopoResImg(key) {
      switch (key) {
        case '虚拟机':
          return require('@/assets/imgs/situation/icon_res_vm.png')
        case '磁盘':
          return require('@/assets/imgs/situation/icon_res_disk.png')
        case '虚拟网络':
          return require('@/assets/imgs/situation/icon_res_network.png')
        case '安全组':
          return require('@/assets/imgs/situation/icon_res_nsg.png')
        case '弹性IP':
          return require('@/assets/imgs/situation/icon_res_ip.png')
        case '浮动IP':
          return require('@/assets/imgs/situation/icon_res_ip.png')
        default:
          return require('@/assets/imgs/situation/icon_res_vm.png')
      }
    },
    /**
     * @description: 获取云商图标
     * @param {*} provider
     * @return {*}
     */
    getProviderImg(provider) {
      switch (provider) {
        case '阿里云':
          return require('@/assets/imgs/situation/img_provider_aliyun.png')
        case '腾讯云':
          return require('@/assets/imgs/situation/img_provider_tencent.png')
        case '华为云':
          return require('@/assets/imgs/situation/img_provider_huawei.png')
        case 'Openstack':
          return require('@/assets/imgs/situation/img_provider_openstack.png')
        case '浪潮InCloud':
          return require('@/assets/imgs/situation/img_provider_inspur.png')
        default:
          return ''
      }
    }
  }
}
</script>

<style lang="less" scoped>
@import "@/assets/css/common.less";
.provider-topo-ctn {
  width: 810px;
  height: 570px;
  background: linear-gradient(
    351deg,
    rgba(52, 85, 120, 0.37) 0%,
    rgba(19, 61, 91, 0.35) 100%
  );

  .topo-root {
    width: 116px;
    height: 194px;
    background: url("~@/assets/imgs/situation/img_topo_root.png") no-repeat;
    background-size: 100% 100%;
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }
  #topo-root-2 {
    top: 32px;
  }
  #topo-root-3 {
    top: 32px;
  }
  #topo-root-4 {
    top: 148px;
  }
  // 云商
  .topo-provider {
    width: 50px;
    height: 50px;
    background: url("~@/assets/imgs/situation/img_provider_aliyun.png")
      no-repeat;
    background-size: 100% 100%;
  }
  #topo-2-provider-1 {
    position: absolute;
    left: 220px;
    top: 50%;
    transform: translateY(-50%);
  }
  #topo-2-provider-2 {
    position: absolute;
    right: 220px;
    top: 50%;
    transform: translateY(-50%);
  }
  #topo-3-provider-1 {
    position: absolute;
    left: 225px;
    top: 188px;
  }
  #topo-3-provider-2 {
    position: absolute;
    right: 225px;
    top: 188px;
  }
  #topo-3-provider-3 {
    position: absolute;
    bottom: 210px;
    left: 50%;
    transform: translateX(-50%);
  }
  #topo-4-provider-1 {
    position: absolute;
    top: 122px;
    left: 200px;
  }
  #topo-4-provider-2 {
    position: absolute;
    top: 122px;
    right: 200px;
  }
  #topo-4-provider-3 {
    position: absolute;
    bottom: 122px;
    left: 200px;
  }
  #topo-4-provider-4 {
    position: absolute;
    bottom: 122px;
    right: 200px;
  }
  // 资源
  .provider-res {
    display: flex;
    flex-direction: column;
    align-items: center;

    // 两个云商的情况
    &.provider-res-2 {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      .topo-res {
        margin-bottom: 36px;
        &:last-child {
          margin-bottom: 0px;
        }
      }
    }
    &.provider-res-2-1 {
      left: 25px;
    }
    &.provider-res-2-2 {
      right: 25px;
    }

    // 三个云商的情况
    &.provider-res-3 {
      position: absolute;
      .res-img {
        height: 33px !important;
      }
    }
    &.provider-res-3-1 {
      top: 30px;
      left: 25px;
      .topo-res {
        margin-bottom: 13px;
        &:last-child {
          margin-bottom: 0px;
        }
      }
    }
    &.provider-res-3-2 {
      top: 30px;
      right: 25px;
      .topo-res {
        margin-bottom: 13px;
        &:last-child {
          margin-bottom: 0px;
        }
      }
    }
    &.provider-res-3-3 {
      width: 700px;
      flex-direction: row;
      justify-content: space-between;
      bottom: 30px;
      left: 55px;
    }

    // 四个云商的情况
    &.provider-res-4 {
      position: absolute;
      .topo-res {
        margin-bottom: 6px;
        &:last-child {
          margin-bottom: 0px;
        }
      }
      .res-img {
        height: 25px !important;
        margin-bottom: 3px !important;
      }
      .res-text {
        height: 18px !important;
        line-height: 16px !important;
      }
    }
    &.provider-res-4-1 {
      left: 35px;
      top: 20px;
    }
    &.provider-res-4-2 {
      right: 35px;
      top: 20px;
    }
    &.provider-res-4-3 {
      left: 35px;
      bottom: 20px;
    }
    &.provider-res-4-4 {
      right: 35px;
      bottom: 20px;
    }

    .topo-res {
      width: 80px;
      display: flex;
      flex-direction: column;
      align-items: center;

      .res-img {
        height: 42px;
        margin-bottom: 8px;
      }
      .res-text {
        box-sizing: border-box;
        padding: 0 6px;
        height: 22px;
        line-height: 20px;
        background: rgba(0, 121, 221, 0.4);
        box-shadow: 0px 0px 4px 0px rgba(67, 227, 225, 0.3);
        border-radius: 2px;
        border: 1px solid #03cdff;
        .textStyle(12px, 600, #30c0ff);
        text-shadow: 0px 0px 4px rgba(67, 227, 225, 0.3);
      }
    }
  }
}
</style>
